package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.NursingPlanDto;
import com.zzyl.dto.NursingProjectPlanDto;
import com.zzyl.entity.NursingPlan;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.NursingPlanMapper;
import com.zzyl.service.NursingPlanService;
import com.zzyl.vo.NursingPlanVo;
import com.zzyl.vo.NursingProjectPlanVo;
import com.zzyl.vo.NursingProjectVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NursingPlanServiceImpl implements NursingPlanService {
    @Autowired
    private NursingPlanMapper nursingPlanMapper;

    /**
     * 条件分页查询
     */
    @Override
    @Transactional
    public PageResponse<NursingPlanVo> queryNursingPlan(String name, Integer pageNum, Integer pageSize, Integer status) {
        PageHelper.startPage(pageNum,pageSize);
        Page<NursingPlan> nursingPlans = nursingPlanMapper.queryNursingPlan(name, status);
        // 判断条件查询的结果是否为空
        if(CollectionUtil.isEmpty(nursingPlans.getResult())){
            return PageResponse.of(nursingPlans,NursingPlanVo.class);
        }
        // 得到每个护理计划ids
        List<Long> ids = nursingPlans.getResult().stream().map(item -> item.getId()).collect(Collectors.toList());
        // 根据护理计划id查询每一个护理计划被引用的次数
        List<Map<String, Object>> maps = nursingPlanMapper.queryNursingPlanByids(ids);
        //  如果没有任何一个护理项目被引用, 直接返回
        if(CollectionUtil.isEmpty(maps)){
            // 返回前先给每一个护理项目的count值设置为 0
            for (NursingPlan nursingPlan : nursingPlans) {
                nursingPlan.setCount(0);
            }
            return PageResponse.of(nursingPlans,NursingPlanVo.class);
        }
        //将护理计划引用数量集合转成Map集合 , 方便后期获取护理计划引用次数 Map<护理目id,关联数量>
        Map<Integer, Long> conutMap = maps.stream().collect(Collectors.toMap(map->Integer.valueOf(map.get("planId").toString()), map -> Long.valueOf(map.get("count").toString())));
        // 将实体类转化为VO
        List<NursingPlanVo> nursingPlanVoList = nursingPlans.getResult().stream().map(item -> {
            NursingPlanVo bean = BeanUtil.toBean(item, NursingPlanVo.class);
            //获取护理项目对应的引用数量
            Long orDefault = conutMap.getOrDefault(item.getId().intValue(),0L);
            bean.setCount(orDefault.intValue());
            return bean;
        }).collect(Collectors.toList());
        return PageResponse.<NursingPlanVo>builder()
                .page(nursingPlans.getPageNum())
                .pageSize(nursingPlans.getPageSize())
                .pages(Long.valueOf(nursingPlans.getPages()))
                .total(nursingPlans.getTotal())
                .records(nursingPlanVoList)
                .build();
    }

    /**
     * 查询所有护理计划
     */
    @Override
    @Transactional
    public List<NursingPlanVo> findNursingPlanList() {
        List<NursingPlan> nursingPlanList = nursingPlanMapper.findNursingPlanList();
        return BeanUtil.copyToList(nursingPlanList, NursingPlanVo.class);
    }

    /**
     * 新增护理计划
     */
    @Override
    @Transactional
    public void addNursingPlan(NursingPlanDto nursingPlanDto) {
        // 因为请求参数类与实体类里面的属性不同，
        // 而实体类中有数据库表的属性，请求参数类没有
        // 所以要先把请求参数类转为实体类，再去存储
        NursingPlan nursingPlan = BeanUtil.toBean(nursingPlanDto, NursingPlan.class);
        // 储存这条护理计划，顺便拿到这条护理计划的id
         nursingPlanMapper.addNursingPlan(nursingPlan);
        Long id = nursingPlan.getId();
        // 给实体类里面的每一条计划执行时间设置项目计划id
        nursingPlan.getProjectPlans().stream().forEach(item->item.setPlanId(id));
        // 拿到实体类里面每一条的计划执行时间
        List<NursingProjectPlanVo> projectPlans = nursingPlan.getProjectPlans();
        // 再把每一条的计划执行时间保存到数据库当中
        for (NursingProjectPlanVo projectPlan : projectPlans) {
            nursingPlanMapper.addNursingPlans(projectPlan);
        }
    }

    /**
     * 根据id查询
     */
    @Override
    @Transactional
    public NursingPlanVo findNursingPlanById(Long id) {
        NursingPlan nursingPlan=nursingPlanMapper.findNursingPlanById(id);
        List<NursingProjectPlanVo> list=nursingPlanMapper.findNursingProjectPlanById(id);
        nursingPlan.setProjectPlans(list);
        return BeanUtil.toBean(nursingPlan,NursingPlanVo.class);
    }

    /**
     * 修改护理计划
     */
    @Override
    public void modifyNursingPlan(NursingPlanDto nursingPlanDto) {
        NursingPlan nursingPlan = BeanUtil.toBean(nursingPlanDto, NursingPlan.class);
        Long id = nursingPlan.getId();
        // 护理计划被引用就不能修改
        List<Map<String, Object>> maps = nursingPlanMapper.queryNursingPlanByids(CollectionUtil.toList(id));
        if(!CollectionUtil.isEmpty(maps)){
            throw new BaseException(BasicEnum.DATA_REFERENCED);
        }
        nursingPlanMapper.deleteNursingPlans(id);
        for (NursingProjectPlanVo projectPlan : nursingPlan.getProjectPlans()) {
            projectPlan.setPlanId(id);
            nursingPlanMapper.addNursingPlans(projectPlan);
        }
    }

    /**
     * 护理计划启用/禁用
     */
    @Override
    public void modifyNursingPlanStatus(Integer id, Integer status) {
        // 护理计划被引用就不能修改                                                   Long转换为List         Integer转换为Long
        List<Map<String, Object>> maps = nursingPlanMapper.queryNursingPlanByids(CollectionUtil.toList(Long.valueOf(id)));
        if(!CollectionUtil.isEmpty(maps)){
            throw new BaseException(BasicEnum.DATA_REFERENCED);
        }
        nursingPlanMapper.modifyNursingPlanStatus(id,status);
    }

    /**
     * 删除护理计划
     */
    @Override
    public void deleteNursingPlan(Integer id) {
        // 护理计划被引用就不能修改                                                   Long转换为List         Integer转换为Long
        List<Map<String, Object>> maps = nursingPlanMapper.queryNursingPlanByids(CollectionUtil.toList(Long.valueOf(id)));
        if(!CollectionUtil.isEmpty(maps)){
            throw new BaseException(BasicEnum.DATA_REFERENCED);
        }
        nursingPlanMapper.deleteNursingPlan(id);
        nursingPlanMapper.deleteNursingPlans(Long.valueOf(id));
    }
}
